home *** CD-ROM | disk | FTP | other *** search
/ Revolution - Das Atari CD Magazin 1997 / Revolution - Das Atari CD Magazin 1.iso / software / anwendng / qed_397 / sourcen / event.c < prev    next >
C/C++ Source or Header  |  1997-01-08  |  12KB  |  562 lines

  1. #include "global.h"
  2. #include "av.h"
  3. #include "clipbrd.h"
  4. #include "dd.h"
  5. #include "disk.h"
  6. #include "edit.h"
  7. #include "find.h"
  8. #include "icon.h"
  9. #include "magx.h"
  10. #include "menu.h"
  11. #include "makro.h"
  12. #include "olga.h"
  13. #include "projekt.h"
  14. #include "rsc.h"
  15. #include "se.h"
  16. #include "set.h"
  17. #include "string.h"
  18. #include "text.h"
  19. #include "windows.h"
  20. #include "event.h"
  21.  
  22. #include "debug.h"
  23.  
  24. /****** DEFINES **************************************************************/
  25.  
  26. #ifndef WM_BOTTOMED
  27. #define WM_BOTTOMED            33
  28. #endif
  29.  
  30. #ifndef WM_ICONIFY
  31. #define WM_ICONIFY            34
  32. #define WM_UNICONIFY            35
  33. #define WM_ALLICONIFY        36
  34. #endif
  35.  
  36. #ifndef SH_WDRAW
  37. #define SH_WDRAW                72
  38. #endif
  39.  
  40. #define MAX_EVENT 20
  41.  
  42. /****** TYPES ****************************************************************/
  43.  
  44. typedef struct
  45. {
  46.     WORD        event;
  47.     WORD        msg[8];
  48.     MKINFO    mk;
  49. }qedEVENT;
  50.  
  51. /****** VARIABLES ************************************************************/
  52.  
  53. LOCAL qedEVENT    msg_queue[MAX_EVENT];
  54. LOCAL WORD        msg_head = 0,
  55.                     msg_tail = 0;
  56. LOCAL WORD        old_mx = 0,
  57.                     old_my = 0;     /* Immer die letzte Mausposition */
  58.  
  59. WORD    abortProg = FALSE;        /* wird TRUE bei SIGTERM */
  60.  
  61. /****** FUNCTIONS ************************************************************/
  62.  
  63. LOCAL VOID hndl_keybd    (MKINFO *mk);
  64. LOCAL VOID hndl_button     (MKINFO *mk);
  65. LOCAL VOID hndl_msg         (WORD *msg, MKINFO *mk);
  66.  
  67. /*****************************************************************************/
  68.  
  69. VOID    gem2mk(WORD kreturn, WORD kstate, MKINFO *mk)
  70. {
  71.     mk->kstate        = kstate;
  72.     mk->scan_code    = kreturn;
  73.     mk->kreturn        = normkey (kstate, kreturn);
  74.     mk->ascii_code    = mk->kreturn & 0x00FF;
  75.     if (mk->kreturn & NKF_SHIFT)            /* beide SHIFT Tasten setzen */
  76.         mk->kreturn |= NKF_SHIFT;
  77.     mk->kreturn   &= ~NKF_CAPS;            /* CAPSLOCK löschen */
  78.     mk->shift        = (kstate & (K_RSHIFT | K_LSHIFT)) != 0;
  79.     mk->ctrl           = (kstate & K_CTRL) != 0;
  80.     mk->alt            = (kstate & K_ALT) != 0;
  81. }
  82.  
  83. LOCAL BOOLEAN is_event(VOID)
  84. {
  85.     return (msg_head!=msg_tail);
  86. }
  87.  
  88. LOCAL BOOLEAN full_event(VOID)
  89. {
  90.     WORD next;
  91.  
  92.     next = msg_head+1;
  93.     if (next==MAX_EVENT)
  94.         next = 0;
  95.     return(next==msg_tail);
  96. }
  97.  
  98. LOCAL VOID add_event(qedEVENT *event)
  99. {
  100.     WORD next;
  101.  
  102.     if (event->event==MU_KEYBD && is_event())            /* Tastatur-Repeat? */
  103.     {
  104.         qedEVENT    *ptr = &msg_queue[msg_tail];
  105.  
  106.         if (ptr->event == MU_KEYBD && ptr->mk.scan_code == event->mk.scan_code &&
  107.             ptr->mk.kstate == event->mk.kstate)
  108.             return;
  109.     }
  110.  
  111.     next = msg_head + 1;
  112.     if (next==MAX_EVENT)
  113.         next = 0;
  114.     if (next==msg_tail)
  115.     {
  116.         inote(1,FATALERR,10);
  117.         return;
  118.     }
  119.     msg_queue[msg_head] = *event;
  120.     msg_head = next;
  121. }
  122.  
  123. LOCAL BOOLEAN get_event(qedEVENT *event)
  124. {
  125.     if (msg_head!=msg_tail)
  126.     {
  127.         *event = msg_queue[msg_tail];
  128.         msg_tail++;
  129.         if (msg_tail==MAX_EVENT) msg_tail = 0;
  130.         return TRUE;
  131.     }
  132.     return FALSE;
  133. }
  134.  
  135. BOOLEAN idle (VOID)
  136. {
  137.     qedEVENT ev;
  138.     WORD        events, kreturn, kstate;
  139.  
  140.     if (full_event())
  141.         return FALSE;
  142.  
  143.     events = MU_KEYBD | MU_BUTTON | MU_MESAG | MU_TIMER;
  144.     if (Mouse_sleeps())
  145.         events |= MU_M2;
  146.     ev.event = evnt_multi (events,
  147.                 0x102, 3, 0,
  148.                 0, 0, 0, 0, 0,
  149.                 1, old_mx, old_my, 1, 1,
  150.                 ev.msg,
  151.                 0, 0,
  152.                 &old_mx, &old_my,
  153.                 &ev.mk.mobutton, &kstate,
  154.                 &kreturn,  &ev.mk.breturn);
  155.     if (ev.event!=MU_TIMER)
  156.     {
  157.         ev.event &= (~MU_TIMER);
  158.         if (ev.event == MU_M2)
  159.             Wake_mouse();
  160.         else
  161.         {
  162.             ev.mk.mox             = old_mx;
  163.             ev.mk.moy             = old_my;
  164.             gem2mk(kreturn, kstate, &ev.mk);
  165.             add_event(&ev);
  166.         }
  167.         return TRUE;
  168.     }
  169.     return FALSE;
  170. }
  171.  
  172. BOOLEAN abbruch (VOID)
  173. {
  174.     qedEVENT ev;
  175.     WORD        events, kreturn, kstate;
  176.  
  177.     if (full_event())
  178.         events = MU_KEYBD | MU_TIMER;
  179.     else
  180.     {
  181.         events = MU_KEYBD | MU_BUTTON | MU_MESAG | MU_TIMER;
  182.         if (Mouse_sleeps())
  183.             events |= MU_M2;
  184.     }
  185.     ev.event = evnt_multi (events,
  186.                   0x102, 3, 0,
  187.                   0, 0, 0, 0, 0,
  188.                   1, old_mx, old_my, 1, 1,
  189.                   ev.msg,
  190.                   0, 0,
  191.  
  192.  
  193.                   &old_mx, &old_my,
  194.                   &ev.mk.mobutton, &kstate,
  195.                   &kreturn,  &ev.mk.breturn);
  196.     if (ev.event!=MU_TIMER)
  197.     {
  198.         ev.event &= (~MU_TIMER);
  199.         if (ev.event==MU_M2)
  200.         {
  201.             Wake_mouse();
  202.             return FALSE;
  203.         }
  204.         ev.mk.mox            = old_mx;
  205.         ev.mk.moy            = old_my;
  206.         gem2mk(kreturn, kstate, &ev.mk);
  207.         if (ev.event & MU_KEYBD)                    /* andere Tasten schlucken */
  208.         {
  209.             return (ev.mk.kreturn & NK_ESC);
  210.         }
  211.  
  212.         add_event(&ev);
  213.     }
  214.     return FALSE;
  215. }
  216.  
  217. LOCAL VOID next_action(qedEVENT *ev)
  218. {
  219.     WINDP window;
  220.     WORD    events, f, kreturn, kstate;
  221.     RECT    r;
  222.  
  223. again:
  224.     if (get_event(ev))                                    /* Event aus der Schlange */
  225.     {
  226.         old_mx = ev->mk.mox;
  227.         old_my = ev->mk.moy;
  228.         if (makro_play)
  229.         {
  230.             if (ev->event != MU_KEYBD)
  231.             {
  232.                 end_play();
  233.                 return;
  234.             }
  235.             else if (ev->mk.kreturn | NK_ESC)
  236.             {
  237.                 end_play();
  238.                 goto again;
  239.             }
  240.         }
  241.         else
  242.             return;
  243.     }
  244.     if (pre_makro(&ev->mk))                             /* Event vom Makro */
  245.     {
  246.         ev->event = MU_KEYBD;
  247.         return;
  248.     }
  249.                                                                 /* auf Event warten */
  250.     events = MU_KEYBD | MU_BUTTON | MU_MESAG | MU_TIMER;
  251.     if (Mouse_sleeps())
  252.         events |= MU_M2;
  253.     if (top() == NULL)
  254.         events &= (~MU_TIMER);
  255.     window = real_top();
  256.     if (window!=NULL && window->flags & WI_MOUSE)    /* Mein Fenster ist oberstes */
  257.     {
  258.         events |= MU_M1;
  259.         r = window->work;
  260.         f = inside(old_mx,old_my,&r);
  261.         if (!f)
  262.         {
  263.             if (Get_mouse()!=ARROW)
  264.                 Arrow_mouse();
  265.         }
  266.         else
  267.         {
  268.             if (Get_mouse()!=window->mousenum)
  269.                 Set_mouse (window->mousenum);
  270.         }
  271.     }
  272.     else
  273.     {
  274.         if (Get_mouse()!=ARROW)
  275.             Arrow_mouse();
  276.     }
  277.     ev->event = evnt_multi (events,
  278.                                   0x102, 3, 0,
  279.                                   f, r.x, r.y, r.w, r.h,
  280.                                   1, old_mx, old_my, 1, 1,
  281.                                   ev->msg,
  282.                                   500, 0,
  283.                                   &old_mx, &old_my,
  284.                                   &ev->mk.mobutton, &kstate,
  285.                                   &kreturn,  &ev->mk.breturn);
  286.     ev->mk.mox             = old_mx;
  287.     ev->mk.moy             = old_my;
  288.     gem2mk(kreturn, kstate, &ev->mk);
  289. }
  290.  
  291. /*****************************************************************************/
  292. /* Ereignis-Verarbeitung                                                                                                         */
  293. /*****************************************************************************/
  294.  
  295. LOCAL VOID hndl_keybd (MKINFO *mk)
  296. {
  297.     WINDOWP window;
  298.  
  299.     post_makro(mk);
  300.     if (!makro_play)
  301.         Sleep_mouse ();
  302.     window = top();                                        /* Taste an TOP-Fenster */
  303.     if (window == NULL)
  304.         window = get_window(0);                            /* DESKTOP suchen */
  305.     if (window == NULL)
  306.         return;
  307.     if (key_window(window,mk))                            /* oberstes Fenster */
  308.         return;
  309.     else
  310.     {
  311.         if (window->class != DESK)                        /* war nicht DESKTOP */
  312.         {
  313.             window = get_window(0);                     /* DESKTOP suchen */
  314.             if (window==NULL)
  315.                 return;
  316.             if (key_window(window,mk))                 /* an Hauptprogramm */
  317.                 return;
  318.         }
  319.     }
  320. }
  321.  
  322. /*****************************************************************************/
  323.  
  324. LOCAL VOID hndl_button (MKINFO *mk)
  325. {
  326.     WORD    wh;
  327.     WINDP window;
  328.  
  329.     if (!all_iconified)
  330.     {
  331.         Wake_mouse();
  332.         wh      = wind_find (mk->mox, mk->moy);         /* Hole Window Handle */
  333.         window = find_window (wh);                         /* Hole Window */
  334.         if (window != NULL)
  335.             click_window(window, mk);                         /* Selektiere */
  336.     }
  337.     else
  338.         if (!no_desktop)
  339.             mybeep();
  340. } /* hndl_button */
  341.  
  342. /*****************************************************************************/
  343.  
  344. LOCAL VOID hndl_msg (WORD *msg, MKINFO *mk)
  345. {
  346.     WINDOWP    window;
  347.     UBYTE        *str_p;
  348.  
  349.     Wake_mouse();
  350.     window= find_window (msg[3]);        /* Zugehöriges Fenster */
  351.  
  352.     switch (msg[0])                            /* Art der Nachricht */
  353.     {
  354.         case MN_SELECTED:
  355.             if (makro_rec)                            /* Makro wird Tastendruck vorgegaukelt */
  356.             {
  357.                 MKINFO    l_mk;
  358.  
  359.                 str_p = (UBYTE *)get_obspec(menu, msg[4]);
  360.                 if (str_to_key(str_p ,&l_mk))
  361.                 {
  362.                     l_mk.kstate |= (mk->kstate&3);
  363.                     post_makro(&l_mk);
  364.                 }
  365.             }
  366.             hndl_menu (msg[3], msg[4], ((mk->kstate & 4) != 0));
  367.             break;
  368.         case WM_REDRAW  :
  369.             redraw_window (window, (RECT*)(msg+4));
  370.             break;
  371.         case WM_CLOSED  :
  372.             if (no_desktop)
  373.                 do_icon(window->link, DO_DESTRUCT);
  374.             else
  375.                 do_icon(window->link, DO_CLOSE);
  376.             break;
  377.         case WM_FULLED  :
  378.             full_window (window);
  379.             break;
  380.         case WM_ARROWED :
  381.             arrow_window (window, msg[4], 1);
  382.             break;
  383.         case WM_HSLID     :
  384.             h_slider (window, msg[4]);
  385.             break;
  386.         case WM_VSLID     :
  387.             v_slider (window, msg[4]);
  388.             break;
  389.         case WM_SIZED     :
  390.             size_window (window, (RECT*)(msg+4), TRUE);
  391.             break;
  392.         case WM_MOVED     :
  393.             move_window (window, (RECT*)(msg+4));
  394.             break;
  395.         case WM_NEWTOP     : /* Fenster von qed ist irgendwie nach oben gekommen */
  396.         case WM_ONTOP     :
  397.             ontop_window(window);
  398.             break;
  399.         case WM_TOPPED  :
  400.             top_window (window);
  401.             do_all_icon(edit_type, DO_UPDATE);    /* Schreibschutz? */
  402.             break;
  403.         case WM_UNTOPPED: /* qed hat jetzt nicht mehr das Top-Fenster */
  404.             untop_window (window);
  405.             break;
  406.         case WM_BOTTOMED:     /* nur gem >= 0x400 : Fenster nach hinten */
  407.         case WM_M_BDROPPED :    /* nur Magic */
  408.             bottom_window (window, msg[0]);
  409.             break;
  410.         case WM_ICONIFY:
  411.             iconify_window(window, (RECT*)(msg+4), FALSE);
  412.             break;
  413.         case WM_ALLICONIFY:
  414.             alliconify((RECT*)(msg+4));
  415.             break;
  416.         case WM_UNICONIFY:
  417.             uniconify_window(window, (RECT*)(msg+4));
  418.             break;
  419.         case AP_TERM:
  420.             if (all_iconified)
  421.                 uniconify_window(NULL, NULL);                /* aufwachen! */
  422.             quick_close = TRUE;
  423.             if (Icon_test(0,DO_DESTRUCT))
  424.                 Icon_edit(0,DO_DESTRUCT);
  425.             break;
  426.         case AP_DRAGDROP :
  427.             if (all_iconified)
  428.                 uniconify_window(NULL, NULL);
  429.             hndl_dd(msg);
  430.             break;
  431.         case SC_CHANGED :
  432.             do_icon(iclipbrd, DO_UPDATE);
  433.             break;
  434.  
  435.         case VA_START :
  436.         case VA_PROTOSTATUS :
  437.         case VA_DRAG_COMPLETE :
  438.             hndl_av(msg);
  439.             break;
  440.  
  441.         case SE_INIT:
  442.         case SE_OK:
  443.         case SE_ACK:
  444.         case SE_OPEN:
  445.         case SE_ERROR:
  446.         case SE_ERRFILE:
  447.         case SE_PROJECT:
  448.         case SE_QUIT:
  449.         case SE_TERMINATE:
  450.         case SE_CLOSE :
  451.         case SE_MENU :
  452.             if (all_iconified)
  453.                 uniconify_window(NULL, NULL);                /* aufwachen! */
  454.            hndl_se(msg);
  455.            break;
  456.  
  457.         case OLGA_INIT :
  458.         case OLE_NEW :
  459.         case OLGA_ACK :
  460.         case OLE_EXIT :
  461.             hndl_OLGA(msg);
  462.             break;
  463.  
  464.         /* ignorieren */
  465.         case SH_WDRAW :
  466.             break;
  467.  
  468.         default:
  469. #ifdef DEBUG
  470.         {
  471.             UBYTE    str[12];
  472.             WORD    d, i, id;
  473.  
  474.             if ((appl_xgetinfo(4, &d, &d, &i, &d)) && (i == 1))    /* gibts appl_search? */
  475.             {
  476.                 i = appl_search(0, str, &d, &id);
  477.                 while (i != 0)
  478.                 {
  479.                     if (d == 2 && id == msg[1])
  480.                         break;
  481.                     i = appl_search( 1, str, &d, &id);
  482.                 }
  483.             }
  484.             Debug("qed: Unbekannte Msg %d (0x%X) von %s (%d)\n", msg[0], msg[0], str, id);
  485.         }
  486. #endif
  487.             break;
  488.     }
  489. } /* hndl_msg */
  490.  
  491. /*****************************************************************************/
  492.  
  493. VOID hndl_events (VOID)
  494. {
  495.     qedEVENT    ev;
  496.     BOOLEAN    menu_chg;
  497.     time_t    t;
  498.  
  499.     updt_menu();
  500.     menu_chg = FALSE;
  501.     onblink_edit();
  502.     do
  503.     {
  504.         quick_close = FALSE;                         /* Sichern der Texte ohne Nachfrage */
  505.         next_action (&ev);
  506.         wind_update (BEG_UPDATE);                    /* Keine Interaktion zulassen */
  507.         get_realtop();
  508.         global_shift = ((ev.mk.kstate & 3) != 0);
  509.  
  510.         if (ev.event == MU_TIMER)                     /* Zeit (nur wenn nichts anderes anliegt) */
  511.         {
  512.             timer_se();
  513.             time(&t);
  514.             local_time = localtime(&t);
  515.             if (blinking_cursor)
  516.                 blink_edit();
  517.             do_icon(iclipbrd, DO_UPDATE);
  518.             do_all_icon(ALL_TYPES, DO_AUTOSAVE);
  519.         }
  520.         if (ev.event & MU_KEYBD)                    /* Taste */
  521.         {
  522.             offblink_edit();
  523.             hndl_keybd(&ev.mk);
  524.             menu_chg = TRUE;
  525.             onblink_edit();
  526.             while (idle()) ;                            /*    Auch für Makro-Play-Abbruch */
  527.         }
  528.         if (ev.event & MU_BUTTON)                    /* Mausknopf */
  529.         {
  530.             offblink_edit();
  531.             hndl_button(&ev.mk);        menu_chg = TRUE;
  532.             onblink_edit();
  533.         }
  534.         if (ev.event & MU_MESAG)                    /* Meldung */
  535.         {
  536.             offblink_edit();
  537.             hndl_msg(ev.msg, &ev.mk);    menu_chg = TRUE;
  538.             onblink_edit();
  539.         }
  540.         if (ev.event & MU_M2)                        /* Maus bewegt */
  541.         {
  542.             Wake_mouse();
  543.         }
  544.         if (menu_chg && !is_event())                /* Wenn Zeit */
  545.         {
  546.             updt_menu();                                /* Eine Aktion kann Menüs verändern */
  547.             menu_chg = FALSE;
  548.         }
  549.         wind_update (END_UPDATE);
  550.         end_undo_seq();
  551.         if (abortProg)
  552.         {
  553.             WORD    msg[] = {0,0,0,0,0,0,0,0};
  554.  
  555.             msg[0] = AP_TERM;
  556.             msg[1] = gl_apid;
  557.             appl_write(gl_apid, 16, msg);
  558.         }
  559.     } while (! done);
  560.     Arrow_mouse ();
  561. } /* hndl_events */
  562.